package main

import (
	"fmt"
)

// func growslice(et *_type, old slice, cap int) slice {
//     if raceenabled {
//         callerpc := getcallerpc(unsafe.Pointer(&et))
//         racereadrangepc(old.array, uintptr(old.len*int(et.size)), callerpc, funcPC(growslice))
//     }
//     if msanenabled {
//         msanread(old.array, uintptr(old.len*int(et.size)))
//     }

//     if et.size == 0 {
//         // 如果新要扩容的容量比原来的容量还要小，这代表要缩容了，那么可以直接报panic了。
//         if cap < old.cap {
//             panic(errorString("growslice: cap out of range"))
//         }

//         // 如果当前切片的大小为0，还调用了扩容方法，那么就新生成一个新的容量的切片返回。
//         return slice{unsafe.Pointer(&zerobase), old.len, cap}
//     }

//   // 这里就是扩容的策略
//     newcap := old.cap
//     doublecap := newcap + newcap
//     if cap > doublecap {
//         newcap = cap
//     } else {
//         if old.len < 1024 {
//             newcap = doublecap
//         } else {
//             for newcap < cap {
//                 newcap += newcap / 4
//             }
//         }
//     }

//     // 计算新的切片的容量，长度。
//     var lenmem, newlenmem, capmem uintptr
//     const ptrSize = unsafe.Sizeof((*byte)(nil))
//     switch et.size {
//     case 1:
//         lenmem = uintptr(old.len)
//         newlenmem = uintptr(cap)
//         capmem = roundupsize(uintptr(newcap))
//         newcap = int(capmem)
//     case ptrSize:
//         lenmem = uintptr(old.len) * ptrSize
//         newlenmem = uintptr(cap) * ptrSize
//         capmem = roundupsize(uintptr(newcap) * ptrSize)
//         newcap = int(capmem / ptrSize)
//     default:
//         lenmem = uintptr(old.len) * et.size
//         newlenmem = uintptr(cap) * et.size
//         capmem = roundupsize(uintptr(newcap) * et.size)
//         newcap = int(capmem / et.size)
//     }

//     // 判断非法的值，保证容量是在增加，并且容量不超过最大容量
//     if cap < old.cap || uintptr(newcap) > maxSliceCap(et.size) {
//         panic(errorString("growslice: cap out of range"))
//     }

//     var p unsafe.Pointer
//     if et.kind&kindNoPointers != 0 {
//         // 在老的切片后面继续扩充容量
//         p = mallocgc(capmem, nil, false)
//         // 将 lenmem 这个多个 bytes 从 old.array地址 拷贝到 p 的地址处
//         memmove(p, old.array, lenmem)
//         // 先将 P 地址加上新的容量得到新切片容量的地址，然后将新切片容量地址后面的 capmem-newlenmem 个 bytes 这块内存初始化。为之后继续 append() 操作腾出空间。
//         memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)
//     } else {
//         // 重新申请新的数组给新切片
//         // 重新申请 capmen 这个大的内存地址，并且初始化为0值
//         p = mallocgc(capmem, et, true)
//         if !writeBarrier.enabled {
//             // 如果还不能打开写锁，那么只能把 lenmem 大小的 bytes 字节从 old.array 拷贝到 p 的地址处
//             memmove(p, old.array, lenmem)
//         } else {
//             // 循环拷贝老的切片的值
//             for i := uintptr(0); i < lenmem; i += et.size {
//                 typedmemmove(et, add(p, i), add(old.array, i))
//             }
//         }
//     }
//     // 返回最终新切片，容量更新为最新扩容之后的容量
//     return slice{p, old.len, newcap}
// }

func main() {
    slice := []int{10, 20, 30, 40}
    newSlice := append(slice, 50)
    fmt.Printf("Before slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
    fmt.Printf("Before newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
    newSlice[1] += 10
    fmt.Printf("After slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
	fmt.Printf("After newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
}